#include "vdefine_test.h"
#include <memory>

constexpr static int g_Size = 1000;
char g_Path[g_Size];

DEF_VIEW_FAIL_FORMAT_FUNC(int) {
    ::printf("param %s match fail is %d, %d!\n", path.OutputPath(g_Path, g_Size), expect, truly);
}

DEF_VIEW_FAIL_FORMAT_FUNC(char) {
    ::printf("param %s match fail is %d, %d!\n", path.OutputPath(g_Path, g_Size), expect, truly);
}

struct A {
    int a;
    char* d;
    char s[10];
};

struct B {
    int b1;
    int b2;
};

struct C {
    A a;
    B b;
    int c;
    B b2;
    int num;
    B array[4];
};

extern auto Test() -> void;
extern auto func() -> void;

int main() {
    using view1 = VSTRUCT(ViewC, C,
                         VVIEW(a, VAPPLY(Viewa),
                                  VVIEW(d),
                                  VCHECK(s[0], 6),
                                  VCHECK(s[1], 'c')),
                         VVIEW(b, VVIEW(b1)),
                         VVIEW(b, VVIEW(b1)),
                         VASSIGN(c, 1),
                         VVIEW(b2.b1),
                         VCHECK(b2.b2, 1));

    using view2 = VSTRUCT(ViewA, A, VAPPLY(Viewa));
    view1 a;
    view2 b;

    A ta;
    ta.a= 2;

    aValue = 1;
    b.IsEqual(ta);
    b.Assign(ta);

    C msg{0};
    msg.a.a = 10;
    msg.a.s[0] = 5;
    msg.a.s[1] = 'c';
    a.IsEqual(msg);

    using view3 = VSTRUCT(ViewCA, C,
                          VVIEW(array[0], VVIEW(b1), VVIEW(b2)),
                          VVIEW(array[1], VVIEW(b1), VVIEW(b2)));

    Test();

    VSTRUCT(ViewCB, C,
            VORARRAY(array, num,
                     VARRAY(VVIEW(b1)),
                     VARRAY(VCHECK(b1, 0))
                     ));

    // todo
    // VSTRUCT(ViewABytes, A, VDECODE(s, len, VVIEW(x));

    // VBASE();
    func();
}
